<?php
/**
 * Created by PhpStorm.
 * User: gqc
 * Date: 2017/1/1
 * Time: 19:55
 */
namespace Api\Service\Amazon;
use Home\Service\CommonService;
use Inbound\Service\PublicInfoService;

class ReportService extends CommonService{
    protected $accountsModel           = NULL;
    protected $reportModel             = NULL;
    protected $reportTypeModel         = NULL;
    protected $reportFileModel         = NULL;
    protected $reportInventoryModel    = NULL;
    protected $reportSaleModel         = NULL;
    protected $reportReceiptsModel     = NULL;
    protected $reportDaySaleModel      = NULL;
    protected $reportRemovalModel      = NULL;
    protected $reportUnsuppressedInventoryModel = NULL;
    protected $reportCurrentInventoryModel = NULL;
    protected $reportSummaryInventoryModel = NULL;
    protected $accountSellerSkuService = NULL;
    private $options           = NULL;
    private $reportDir         = '';
    private $content           = '';
    private static $sleepTime       = 10;
    private static $loopNum         = 3;
    private static $decodeBlackList = array('jp');
    private static $grabTrackLogs = array();

    public function __construct() {
        $this->reportModel             = D('Api/Amazon/Report','Model');
        $this->reportTypeModel         = D('Api/Amazon/ReportType','Model');
        $this->accountsModel           = D('Api/Amazon/Accounts','Model');
        $this->reportFileModel         = D('Api/Amazon/ReportFile','Model');
        $this->reportSaleModel         = D('Api/Amazon/ReportSale','Model');
        $this->reportInventoryModel    = D('Api/Amazon/ReportInventory','Model');
        $this->reportFulfilledShipmentsModel    = D('Api/Amazon/ReportFulfilledShipments','Model');
        $this->reportReceiptsModel     = D('Api/Amazon/ReportReceipts','Model');
        $this->reportDaySaleModel      = D('Api/Amazon/ReportDaySale','Model');
        $this->reportUnsuppressedInventoryModel = D('Api/Amazon/ReportUnsuppressedInventory','Model');
        $this->reportRemovalModel      = D('Api/Amazon/ReportRemoval', 'Model');
        $this->reportSummaryInventoryModel      = D('Api/Amazon/ReportSummaryInventory', 'Model');
        $this->reportCurrentInventoryModel      = D('Api/Amazon/ReportCurrentInventory', 'Model');
        $this->reportRemovalModel      = D('Api/Amazon/ReportRemoval', 'Model');

        $this->accountSellerSkuService = D('Api/Amazon/accountSellerSku', 'Service');

        $this->reportDir               = dirname(THINK_PATH) . '/Public/report/';
        self::$grabTrackLogs = array();

    }

    /**
     * 描述：RequestReport、ReportRequestList、ReportList、getReport调用获取报告
     * 参数：$accounts Array(),$options  Array()
     */
    public function getReport($options,$accountId = null){
        set_time_limit(0);
        ini_set('memory_limit','1024M');
        $reportType = $this->reportTypeModel->getReportTypeByID($options['report_type']);
        if($accountId){
            $accounts[] = $this->accountsModel->getAccountById($accountId);
        }else{
            $accounts = $this->accountsModel->getAccounts();
        }

        $params = array();
        $params['ReportType'] = $reportType['report_type'];
        if($reportType['id'] == 1){
            date_default_timezone_set("UTC");
            $params['StartDate']    = date('Y-m-d', strtotime('-2 day'));
            $params['EndDate']    = date('Y-m-d', strtotime('-1 day'));
            date_default_timezone_set("PRC");
        }
        if($reportType['id'] == 4){
            $params['StartDate']    = date('Y-m-d', strtotime('-7 month'));
        }

        if ($reportType['id'] == 5) {
            $params['StartDate']    = date('Y-m-d', strtotime('-1 day'));
            $params['EndDate']    = date('Y-m-d', strtotime('-2 day'));
        }

        if(in_array($reportType['id'], array(6,7,9))) {
            $params['StartDate'] = $options['StartDate'];
            $params['EndDate'] = $options['EndDate'];
        }

        /*抓取销量报告和库存报告跨帐号跑，抓取在途库存和入库时间跑所有帐号*/
        $i = 0;
        foreach($accounts as $k => $account){
            if($i % 10 == 0) {
                sleep(self::$sleepTime * 2);
            }

            if(!isset($haveFetchMerchants[$account['merchant_id']])) {
                $haveRunCron = $this->checkCronRun($reportType, $account['id']);
                if ($haveRunCron) continue;
                $options = array();
                $options['Merchant']    = $account['merchant_id'];
                $options += $params;
                $this->options[$account['id']] = $options;

                //追踪抓取日志
                self::$grabTrackLogs[$account['id']]['account_id'] = $account['id'];
                self::$grabTrackLogs[$account['id']]['account_name'] = $account['name'];
                self::$grabTrackLogs[$account['id']]['merchant_id'] = $account['merchant_id'];
                self::$grabTrackLogs[$account['id']]['report_type_id'] = $reportType['id'];
                self::$grabTrackLogs[$account['id']]['report_request_time'] = date('Y-m-d H:i:s');

                if($reportRequestId = $this->goRequestReport($account, $options)) {
                    $haveFetchMerchants[$account['merchant_id']] = $reportRequestId;//给的帐号都是要抓的
                    $reportRequestIds[$account['id']] = $reportRequestId;

                    //追踪抓取日志
                    self::$grabTrackLogs[$account['id']]['report_id'] = $reportRequestId;
                } else {
                    //追踪抓取日志
                    self::$grabTrackLogs[$account['id']]['report_id'] = 0;
                }
            }

            $i++;
        }

        sleep(self::$sleepTime * 24);

        /*获取报告到本地和数据表*/
        $filesInfos = array();
        $i = 0;
        foreach($accounts as $account) {
            if($i % 10 == 0) {
                sleep(self::$sleepTime * 2);
            }

            if(isset($reportRequestIds[$account['id']])) {
                $options = array();
                $options['Merchant']    = $account['merchant_id'];
                $options['ReportRequestIdList']    = array('Id'=>array($reportRequestIds[$account['id']]));

                //追踪抓取日志
                self::$grabTrackLogs[$account['id']]['file_request_time'] = date('Y-m-d H:i:s');
                $fileInfo = $this->getReportFileList(
                    $account,
                    $this->goGetReportRequestList($account, $options),
                    $reportType['id']
                );

                if(empty($fileInfo)) {
                    self::$grabTrackLogs[$account['id']]['file'] = 0;
                    continue;
                }

                //追踪抓取日志
                self::$grabTrackLogs[$account['id']]['file'] = 1;
                $filesInfos[$account['name']] = $fileInfo;
            }

            $i++;
        }

        $reportTableName = '';
        //可以替换的代码,代替下面的语句
        $reportTableName = $reportType['table_name'];
        /*switch ($reportType['id']){
            case 1:
                $reportTableName = 'api_report_sale';
                break;
            case 2:
                $reportTableName = 'api_report_unsuppressed_inventory';
                break;
            case 3:
                $reportTableName = 'api_report_inventory';
                break;
            case 4:
                $reportTableName = 'api_report_receipts';
                break;
            case 5:
                $reportTableName = 'api_report_removal';
                break;
            case 6:
                $reportTableName = 'api_report_currentInventory';
                break;
            case 7:
                $reportTableName = 'api_report_summaryInventory';
        }*/

        /*解析报告插入到数据库并计算数据表*/
        foreach ($filesInfos as $accountName => $singleFile) {
            list($amazonReportId, $reportFileName) = each($singleFile);
            if($reportType['id'] == 1) {

                $this->analysisReportToTable($reportFileName, $amazonReportId, $reportTableName);

                $reportFile = $this->reportFileModel->getReportFile($reportFileName);
                $this->reportSaleModel->saleTodaySale($reportFile['id']);
                $this->reportDaySaleModel->daySaleCalculate($reportFile['account_id']);
            }elseif ($reportType['id'] == 2) {
                $this->reportUnsuppressedInventoryModel->shippingCalculate(
                    $this->analysisReportToTable($reportFileName, $amazonReportId, $reportTableName));
            }elseif ($reportType['id'] == 3) {
                $this->reportInventoryModel->stockCalculate(
                    $this->analysisReportToTable($reportFileName, $amazonReportId, $reportTableName));
            }else{
                $this->analysisReportToTable($reportFileName, $amazonReportId, $reportTableName);
            }
        }

        //echo $this->content;
        //追踪抓取日志
        foreach (self::$grabTrackLogs as $trackLog) {
            $sql = 'INSERT INTO `api_report_track_log` (' . join(',', array_keys($trackLog)) . ') VALUES ';
            $sql .= '(\'' . join('\', \'', $trackLog) . '\')';
            M('report_track_log', 'api_', 'DB_FBAERP')->query($sql);
        }

        return 'Done';

    }

    /**
     * 创建报告请求，并将请求提交至亚马逊 MWS
     */
    public function goRequestReport($account, $options) {
        if(!isset($options['ReportType'])) {
            return false;
        }

        $try_times = 0;
        while($try_times < self::$loopNum){
            $try_times ++;
            $report_data            = $this->reportModel->RequestReport($account, $options);

            if(!isset($report_data['ReportRequestId'])){
                $this->content .= $account['name'] . '发送生成报告请求失败 ' . $this->reportModel->getError();

                /*无权访问，直接退出*/
                if(strpos($this->content, 'denied') !== false) {
                    return false;
                }

                sleep(self::$sleepTime/2);
                continue;
            }

            return $report_data['ReportRequestId'];
        }

        return false;
    }

    /**
     * 根据账号、类型和generateReportId获取文件到本地
     */
    public function getReportFileList ($account, $generatedReportIds, $reportTypeId) {
        $result = array();

        if(isset($generatedReportIds['GeneratedReportId'])) {
            foreach($generatedReportIds['GeneratedReportId'] as $generatedReportId) {
                $reportFileName = $this->goGetReport($account, $generatedReportId, $reportTypeId);
                $reportFileName && $result[$generatedReportId] = $reportFileName;
            }
        } else {
            if(isset($generatedReportIds['_DONE_'])) {
                foreach($generatedReportIds['_DONE_'] as $reportRequestId) {
                    $options = array();
                    $options['Merchant']            = $account['merchant_id'];
                    $options['ReportRequestIdList']    = array('Id'=>array($reportRequestId));
                    $reportId = $this->goGetReportList($account, $options);

                    if(isset($reportId[0]) && $reportId[0]) {
                        $reportFileName = $this->goGetReport($account, $reportId[0], $reportTypeId);
                        $reportFileName && $result[$reportId[0]] = $reportFileName;
                    }
                }
            }
        }

        return $result;
    }

    /**
     * 返回可用于获取报告的 ReportRequestId 的报告请求列表，抓取前，应给足亚马逊时间生成报告
     */
    public function goGetReportRequestList ($account, $options) {
        $re = array();
        $try_times = 0;
        while($try_times < self::$loopNum){
            $try_times ++;

            $report_data            = $this->reportModel->getReportRequestList($account, $options);

            if(!empty($report_data)) {
                foreach($report_data as $report) {
                    if(!isset($report['ReportProcessingStatus']))continue;

                    if($report['ReportProcessingStatus'] == '_DONE_') {
                        if(isset($report['GeneratedReportId'])) {
                            $re['GeneratedReportId'][] = $report['GeneratedReportId'];
                        } else {
                            $re['_DONE_'][] = $report['ReportRequestId'];
                        }
                    } elseif(in_array($report['ReportProcessingStatus'], array('_DONE_NO_DATA_', '_CANCELLED_'))) {
                        $noData[] = $report['ReportRequestId'];
                    } else {
                        $needTryAgain[] = $report['ReportRequestId'];
                    }
                }

                if(isset($needTryAgain)) {
                    $this->content .= $account['name'] . '在getReportRequestList接口中请求成功但含有未完成状态ReportRequestId</br>';

                    unset($needTryAgain);
                    sleep(self::$sleepTime * 5);
                    continue;
                } elseif (!empty($re)) {
                    $this->content .= $account['name'] . '在getReportRequestList接口中请求成功!</br>';

                    return $re;
                }
            }

            $this->content .= $account['name'] . '在getReportRequestList接口中请求获取报告状态失败' . $this->reportModel->getError() . '</br>';

            if(isset($noData)){
                $this->content .= join(',',$noData) . "没有数据!";
                return false;
            }

            sleep(self::$sleepTime/2);
            continue;
        }

        return false;
    }

    /**
     * 返回在过去 90 天内所创建的报告列表或者返回指定列表
     */
    public function goGetReportList($account, $options) {
        $re = array();
        $try_times = 0;
        while($try_times < self::$loopNum){
            $try_times ++;

            $report_data = $this->reportModel->GetReportList($account, $options);

            if(!empty($report_data)) {
                foreach($report_data as $report) {
                    if(isset($report['ReportId']))
                        $re[] = $report['ReportId'];
                    else
                        $needTry[] = isset($report['ReportRequestId']) ? $report['ReportRequestId'] : '';
                }

                if(isset($needTry)) {
                    $content['content'] = $account['name'] . '在GetReportList接口中请求成功，但是有部分没有返回ReportId!</br>';

                    sleep(self::$sleepTime/2);
                    continue;
                } elseif (!empty($re)) {
                    $content['content'] = $account['name'] . '在GetReportList接口中请求报告列表成功!</br>';

                    return $re;
                }
            }

            $this->content .= $account['name'] . '在GetReportList接口中请求获取报告列表失败' . $this->reportModel->getError() . "</br>";

            sleep(self::$sleepTime);
            continue;
        }

        return false;
    }



    /**
     * 返回报告内容及所返回报告正文的 Content-MD5 标头
     */
    public function goGetReport ($account, $ReportId, $reportTypeId) {
        if(empty($ReportId))return false;

        $try_times = 0;
        while($try_times < self::$loopNum){
            $try_times++;

            $report_data            = $this->reportModel->GetReport($account, $ReportId);

            if(!$report_data){
                $this->content .= $account['name'] . '在GetReport接口中抓取编号 '.$ReportId.'结算报告失败: '.$this->reportModel->getError() . '</br>';

                sleep(self::$sleepTime/3);
                continue;
            }

            $md5 = base64_encode(md5($report_data['Data'],TRUE));

            if($report_data['ContentMd5'] != $md5){
                $this->content .= $account['name'] . '在GetReport接口中抓取编号 ' . $ReportId . ' 结算报告数据不完整，MD5校验失败!</br>';

                sleep(self::$sleepTime/2);
                continue;
            }

            if(!is_readable($this->reportDir . $reportTypeId . '/' . $account['name'])){
                $this->mk_dirs($this->reportDir . $reportTypeId . '/' . $account['name']);
            }
            if(!is_readable($this->reportDir . $reportTypeId . '/' . $account['name'])){
                $this->content .= $account['name'] . '在GetReport接口中抓取编号 ' . $ReportId. ' 结算报告成功，写入文件夹' .
                    $this->reportDir . $reportTypeId . '/' . $account['name'] . '时失败，请检查是否有权限';
                break;
            }

            $report_data_file_name = $account['id'] . '-' .
                date('Y-m-d_H-i-s').'-' . $ReportId . '.txt';
            $report_data_path = $this->reportDir . $reportTypeId . '/' . $account['name'] . '/' . $report_data_file_name;

            if(file_put_contents($report_data_path, $report_data['Data']) === FALSE){
                $this->content .= $account['name'] . '在GetReport接口中抓取编号 '.$ReportId .
                    ' 结算报告成功，写入文件'.$report_data_path.'时失败，请检查是否有权限!</br>';
                break;
            }

            $this->content .= $account['name'] . '在GetReport接口中抓取编号 '.$ReportId.' 结算报告成功!</br>';

            $report_files = array();
            $report_files['account_id'] = $account['id'];
            $report_files['account_name'] = $account['name'];
            $report_files['report_id'] = $ReportId;
            $report_files['report_type_id'] = $reportTypeId;
            $report_files['options'] = serialize($this->options[$account['id']]);
            $report_files['file_name'] = $report_data_file_name;
            $report_files['create_time'] = date('Y-m-d H:i:s');

            $insertFileDataId = $this->reportFileModel->insertReportFileData($report_files);
            if($insertFileDataId){
                $this->content .= $account['name'] . '帐号的 ' . $ReportId . " 插入数据表 api_report_files成功！</br>";
            }else
                $this->content .= $account['name'] . '帐号的 ' . $ReportId . " 插入数据表 api_report_files失败！</br>";

            return $report_data_file_name;
        }
    }




    /**
     * ReportType 指明待请求报告的类型
     * StartDate 用于选择待报告数据日期范围的起始日期
     * EndDate 用于选择待报告数据日期范围的结束日期
     */
    public function getRequestReport($accountId,$options = array()){
        if(empty($options['ReportType'])) return null;

        $account = $this->accountsModel->getAccountById($accountId);
        if(empty($account))return array();

        $reportRequestResult = $this->reportModel->requestReport($account,$options);
        $options['ReportRequestIdList'] = array('Id'=>array($reportRequestResult['ReportRequestId']));

        $this->getReportRequestList($account,$options);
        return $reportRequestResult;


    }

    /**
     * ReportRequestId 值的结构化列表。如果您传入 ReportRequestId 的值，则会忽略其他查询条件。
     */
    public function getReportRequestList($accountId,$options = array()){
        if(empty($options['ReportRequestIdList'])) return null;

        $account = $this->accountsModel->getAccountById($accountId);
        if(empty($account))return array();

        $getReportRequestListResult = $this->reportModel->getReportRequestList($account,$options);

        return $getReportRequestListResult;
    }

    /**
     * ReportRequestId 如果您传入 ReportRequestId 的值，则会忽略其他查询条件。
     */
    public function getReportList($accountId,$options = array()){
        if(empty($options['ReportRequestIdList'])) return null;

        $account = $this->accountsModel->getAccountById($accountId);
        if(empty($account))return array();

        $getReportListResult = $this->reportModel->getReportList($account,$options);

        print_r($getReportListResult);exit;
        return $getReportListResult;
    }

    /**
     * ReportId 通过 GetReportList 操作或 ReportRequest 的 GeneratedReportId 而获取
     */
    public function getReport1($accountId,$reportId){
        if(empty($reportId)) return null;

        $account = $this->accountsModel->getAccountById($accountId);
        if(empty($account))return array();

        $getReportResult = $this->reportModel->getReport($account,$reportId);

        $md5 = base64_encode(md5($getReportResult['Data'],TRUE));

        if($getReportResult['ContentMd5'] != $md5) {
            return array();
        }



        print_r($getReportResult);exit;
        return $getReportResult;
    }



    /**
     * @param null  $file_name
     * @param null  $report_id
     * @param       $table_name
     * @param array $notInCols
     * @return bool
     * 将文件报告解析到数据库
     */
    public function analysisReportToTable ($fileName = NULL, $reportId = NULL, $tableName, $notInCols= array()) {
        $reportFile = $this->reportFileModel->getReportFile($fileName, $reportId);
        if(empty($reportFile))return false;

        $reportFilePath = $this->reportDir . $reportFile['report_type_id'] . '/' . $reportFile['account_name']. '/' .$reportFile['file_name'];

        /*$cols = $this->reportFileModel->getTableColumns(
            $tableName,
            array_merge($notInCols, array(
                'id', 'account_id', 'account_name', 'report_file_id', 'create_time', 'update_time'
            ))
        );*/

        //追踪抓取日志
        self::$grabTrackLogs[$reportFile['account_id']]['analysis_begin_time'] = date('Y-m-d H:i:s');

        $rowLists = $this->goAnalysisReport(
            $reportFile,
            $reportFilePath
            //$cols
        );

        if(!empty($rowLists) && !empty($_GET['sp'])) {
            foreach ($rowLists as $row) {
                $data['account_id']=isset($row['account_id']) ? $row['account_id'] : '';
                $data['amazon_order_id']=isset($row['amazon_order_id']) ? $row['amazon_order_id'] : '';
                $data['shipment_id']=isset($row['shipment_id']) ? $row['shipment_id'] : '';
                $data['shipment_item_id']=isset($row['shipment_item_id']) ? $row['shipment_item_id'] : '';
                $data['amazon_order_item_id']=isset($row['amazon_order_item_id']) ? $row['amazon_order_item_id'] : '';
                $data['purchase_date']=isset($row['purchase_date']) ? $row['purchase_date'] : '';
                $data['payments_date']=isset($row['payments_date']) ? $row['payments_date'] : '';
                $data['shipment_date']=isset($row['shipment_date']) ? $row['shipment_date'] : '';
                $data['reporting_date']=isset($row['reporting_date']) ? $row['reporting_date'] : '';
                $data['buyer_email']=isset($row['buyer_email']) ? $row['buyer_email'] : '';
                $data['buyer_name']=isset($row['buyer_name']) ? $row['buyer_name'] : '';
                $data['buyer_phone_number']=isset($row['buyer_phone_number']) ? $row['buyer_phone_number'] : '';
                $data['sku']=isset($row['sku']) ? $row['sku'] : '';
                $data['product_name']=isset($row['product_name']) ? $row['product_name'] : '';
                $data['quantity_shipped']=isset($row['quantity_shipped']) ? $row['quantity_shipped'] : '';
                $data['currency']=isset($row['currency']) ? $row['currency'] : '';
                $data['item_price']=isset($row['item_price']) ? $row['item_price'] : '';
                $data['shipping_price']=isset($row['shipping_price']) ? $row['shipping_price'] : '';
                $data['ship_service_level']=isset($row['ship_service_level']) ? $row['ship_service_level'] : '';
                $data['recipient_name']=isset($row['recipient_name']) ? $row['recipient_name'] : '';
                $data['ship_address_1']=isset($row['ship_address_1']) ? $row['ship_address_1'] : '';
                $data['ship_address_2']=isset($row['ship_address_2']) ? $row['ship_address_2'] : '';
                $data['ship_address_3']=isset($row['ship_address_3']) ? $row['ship_address_3'] : '';
                $data['ship_city']=isset($row['ship_city']) ? $row['ship_city'] : '';
                $data['ship_state']=isset($row['ship_state']) ? $row['ship_state'] : '';
                $data['ship_postal_code']=isset($row['ship_postal_code']) ? $row['ship_postal_code'] : '';
                $data['ship_country']=isset($row['ship_country']) ? $row['ship_country'] : '';
                $data['carrier']=isset($row['carrier']) ? $row['carrier'] : '';
                $data['tracking_number']=isset($row['tracking_number']) ? $row['tracking_number'] : '';
                $data['estimated_arrival_date']=isset($row['estimated_arrival_date']) ? $row['estimated_arrival_date'] : '';
                $data['fulfillment_center_id']=isset($row['fulfillment_center_id']) ? $row['fulfillment_center_id'] : '';
                $data['fulfillment_channel']=isset($row['fulfillment_channel']) ? $row['fulfillment_channel'] : '';
                $data['sales_channel']=isset($row['sales_channel']) ? $row['sales_channel'] : '';

                $this->reportFulfilledShipmentsModel->add($data);
            }
        }

        //追踪抓取日志
        self::$grabTrackLogs[$reportFile['account_id']]['analysis_end_time'] = date('Y-m-d H:i:s');
        self::$grabTrackLogs[$reportFile['account_id']]['db_begin_time'] = date('Y-m-d H:i:s');
        empty($_GET['sp']) && $this->fileContentToDbTable ($tableName, $rowLists,$reportFile['account_id']);
        self::$grabTrackLogs[$reportFile['account_id']]['db_end_time'] = date('Y-m-d H:i:s');

        return $reportFile['id'];
    }

    /**
     * @param null $file_name
     * @param null $report_id
     * @return array|bool
     * 根据报告ID或者文件名字获取报告信息
     */
    /*public function getReportFile ($fileName = NULL, $reportId = NULL) {
        if(empty($fileName) && empty($reportId))return false;

        $sql = 'SELECT * FROM `api_report_files` WHERE 1';
        !empty($fileName) && $sql .= ' AND `file_name` = \''. $fileName .'\'';
        !empty($reportId) && $sql .= ' AND `report_id` = '. $reportId;

        $reportFile = M('report_files', 'api_', 'DB_fbawarehouse')->query($sql);

        return empty($reportFile) ? array() : $reportFile[0];
    }*/

    /**
     * 返回某张表的所有字段
     */
    /*public static function getTableColumns ($tbl, $notInCol = array()) {
        if(empty($tbl)) return false;
        $cols = array();
        $sql = "SELECT COLUMN_NAME
            FROM information_schema.COLUMNS
            WHERE table_name = '{$tbl}' ";

        !empty($notInCol) && $sql .="AND COLUMN_NAME NOT IN('" . join("', '", $notInCol) . "')";
        $tblColumns = M($tbl, ' ', 'DB_fbawarehouse')->query($sql);
        foreach ($tblColumns as $tblColumn) {
            $cols[] = $tblColumn['COLUMN_NAME'];
        }

        return $cols;
    }*/

    /**
     * 解析文件，根据cols获取目标值
     */
    public function goAnalysisReport($reportFile, $filePath, $cols = array()) {
        $sites = PublicInfoService::get_site_array();
        if(empty($filePath))return false;
        //$isSaleType = ($report_file['report_type_id'] == 1);
        /*$model_sku = D('Sku');
        $sites = $this->getAccountsSites();
        $sufs = $this->getSkuPreSuf();*/
        /*$sql = 'UPDATE `api_report_files`
        SET `analyze_status` = 1, `analyze_time` = \'' . date('Y-m-d H:i:s') . '\'
        WHERE `id` = ' . $reportFile['id'];
        M('report_files', 'api_', 'DB_fbawarehouse')->query($sql);*/
        $this->reportFileModel->updateAnalyzeStatus($reportFile['id']);
        //$reportAccountsGroup = $this->getAccountsGroup($report_file['account_id'], $report_file['type']);

        $f = @fopen($filePath, 'r');

        $lists = $re = array();
        $rowLine = 0;
        while(!feof($f)) {
            $rowLine ++;
            $row = fgets($f);
            if(empty($row))continue;

            if(!isset($headers)) {
                $row = $this->checkIsDecodeBlackReport($reportFile, $row);
                if(!empty($row)) {
                    $rowArr = explode("\t", $row);
                    if(empty($rowArr) || empty($rowArr[0]))continue;
                    $headers = self::trimArray($rowArr);
                    continue;
                }
            }

            $rowArr = explode("\t", $row);
            if(empty($rowArr) || empty($rowArr[0]))continue;

            $list = array();
            foreach($headers as $num => $col) {
                if($col == 'seller-sku') {
                    $list['sku'] = htmlspecialchars_decode(trim($rowArr[$num]));
                    continue;
                }
                $list[preg_replace('/-/','_',$col)] = trim($rowArr[$num]);
            }

            if(!isset($brotherAccountIds)){
                $brotherAccountIds = D('Api/Amazon/AccountSite','Model')->getBrotherAccountIds($reportFile['account_id']);
            }

            if($reportFile['report_type_id'] == 1){
                $accountId = false;
                if($list['sales_channel'] == 'Non-Amazon') continue;
                if (strpos($list['sales_channel'],'.')) {
                    $salesChannel = substr($list['sales_channel'],strpos($list['sales_channel'],'.')+1);
                    $accountId = D('Api/Amazon/AccountSite','Model')->getAccountIdBySaleChannel($reportFile['account_id'],$salesChannel);
                }
                if (!$accountId) {
                    //$brotherAccountIds = D('Api/Amazon/AccountSite','Model')->getBrotherAccountIds($reportFile['account_id']);
                    $condition['seller_sku'] = array('EQ',$list['sku']);
                    $condition['account_id'] = array('IN',implode(',',$brotherAccountIds));
                    $accountId = D('Api/Amazon/AccountSellerSku','Model')->selectSku($condition);
                    $accountId = $accountId[0]['account_id'];
                }

                //抓取追踪日志
                if(!$accountId) {
                    $accountId = 0;
                    !isset(self::$grabTrackLogs[$reportFile['account_id']]['error_log']) &&
                    self::$grabTrackLogs[$reportFile['account_id']]['error_log'] = 'Account：' . $reportFile['account_id'] . ' has no troop';
                }

                $list['account_id'] = $accountId;
            }elseif($reportFile['report_type_id'] == 3){
                $country = $list['country'];
                $country == 'UK' && $country = 'GB';
                $accountId = D('Api/Amazon/AccountSite','Model')->getAccountIdByCountry($reportFile['account_id'],$country);

                if (!$accountId) {
                    //$brotherAccountIds = D('Api/Amazon/AccountSite','Model')->getBrotherAccountIds($reportFile['account_id']);
                    $condition['seller_sku'] = array('EQ',$list['sku']);
                    $condition['account_id'] = array('IN',implode(',',$brotherAccountIds));
                    $accountId = D('Api/Amazon/AccountSellerSku','Model')->selectSku($condition);
                    $accountId = $accountId[0]['account_id'];
                }

                $list['account_id'] = $accountId ? $accountId : 0;
            }elseif($reportFile['report_type_id'] == 6 || $reportFile['report_type_id'] == 7){
                $site = $sites[PublicInfoService::get_siteid_by_accountid($reportFile['account_id'])];
                if($reportFile['report_type_id'] == 6){
                    if($list['country']=='CZ' || $list['country']=='PL'){
                        $country = 'DE';
                    }else{
                        $country = $list['country'];
                    }
                    if($site != $country){
                        continue;
                    }
                }else{
                    if($site != 'JP' && $site != 'US'){
                        $condition['seller_sku'] = array('EQ',$list['sku']);
                        $condition['account_id'] = array('EQ',$reportFile['account_id']);
                        $accountId = D('Api/Amazon/AccountSellerSku','Model')->selectSku($condition);
                        $accountId = $accountId[0]['account_id'];
                        if(!$accountId){
                            continue;
                        }
                    }
                }
                $list['account_id'] = $reportFile['account_id'];

            }/*elseif($reportFile['report_type_id'] == 4){
                $list['received_date'] = substr($list['received_date'], 0, 10);
                $list['account_id'] = $reportFile['account_id'];
            }*/else{


                $condition['seller_sku'] = array('EQ',$list['sku']);
                $condition['account_id'] = array('IN',implode(',',$brotherAccountIds));

                $accountId = D('Amazon\AccountSellerSku')->selectSku($condition);
                $list['account_id'] = $accountId[0]['account_id'] ? $accountId[0]['account_id'] : 0;

                if($reportFile['report_type_id'] == 4){
                    $list['received_date'] = substr($list['received_date'], 0, 10);
                }
                if ($reportFile['report_type_id'] == 5) {
                    $list['request_date'] = substr($list['request_date'], 0, 10);
                    $list['last_updated_date'] = substr($list['last_updated_date'], 0, 10);
                }
            }

            $list['account_id'] = !$list['account_id'] ? $reportFile['account_id']  : $list['account_id'];
            $list['report_file_id'] = $reportFile['id'];

            $lists[] = $list;
            /*isset($list['sku']) &&
            $list['sku'] = preg_replace('/(.*?)\s(#|@)/i', '${1}$2', strtoupper(trim($list['sku'])));*/

//            if(!empty($cols)) {
//                $re_child = array();
//                $kCol = $isSaleType ? 'sales-channel' : 'country';
//
//                in_array('seller-sku', $cols) && $cols[array_search('seller-sku', $cols)] = 'sku';
//                $decodeSkuInfos = $model_sku->decode($re_child['sku'] = trim($list['sku']));
//                $re_child['sku_clean'] = $model_sku->clean($re_child['sku']);
//                $re_child['sku_serialized'] = serialize($decodeSkuInfos);
//
//                foreach ($decodeSkuInfos as $k=>$decodeSkuInfo) {
//                    $skuGoods = array();
//
//                    foreach($cols as $col) {
//                        if($col == 'sku') {
//                            $skuGoods['sku_base'] = $decodeSkuInfo['sku'];
//
//                            /*前后缀特殊符号处理*/
//                            $pre2 = strtoupper(substr($decodeSkuInfo['sku'], 0, 2));
//                            $pre3 = strtoupper(substr($decodeSkuInfo['sku'], 0, 3));
//                            $suf2 = strtoupper(substr($decodeSkuInfo['sku'], -2));
//                            $suf3 = strtoupper(substr($decodeSkuInfo['sku'], -3));
//
//                            if(in_array($pre = $pre2, $sufs['PREFIX']) || in_array($pre = $pre3, $sufs['PREFIX']))
//                                $skuGoods['sku_base'] = ltrim($skuGoods['sku_base'], $pre);
//
//                            if(in_array($last = $suf2, $sufs['SUFFIX']) || in_array($last = $suf3, $sufs['SUFFIX']))
//                                $skuGoods['sku_base'] = rtrim($skuGoods['sku_base'], $last);
//
//                            /*如果是SP结尾则为西班牙ES站点的*/
//                            $suf2 == 'SP' && $suf2 = 'ES';
//
//                            /*判断是哪个站点的库存*/
//                            if(in_array($suf = $suf2, $sites) || in_array($suf = $suf3, $sites)) {
//                                $skuGoods['sku_base'] = rtrim($skuGoods['sku_base'], $suf);
//
//                                if(!$isSaleType && $suf != 'UK') {
//                                    $re_child['account_id'] = $reportAccountsGroup[$suf]['account_id'];
//                                    $re_child['account_name'] = $reportAccountsGroup[$suf]['account_name'];
//                                }
//                            }
//
//                            $skuGoods['sku_base_quantity'] = $decodeSkuInfo['quantity'];
//                        } elseif($k == 0 && !in_array($col, array(
//                                'sku_clean', 'sku_serialized', 'sku_base', 'sku_base_quantity'
//                            ))
//                        ) {
//                            if(!isset($list[$col])) {
//                                $log_decode = array();
//                                $log_decode['report_file_id'] = $report_file['id'];
//                                $log_decode['row_num'] = $row_line;
//                                $log_decode['message'] = '字段' . $col . '在该行不存在';
//                                $this->decodeFileLog($log_decode);
//
//                                continue 2;
//                            }
//                            $re_child[$col] = $list[$col];
//                        }
//                    }
//
//                    !isset($re_child['account_id']) &&
//                    $re_child['account_id'] = $reportAccountsGroup[$re_child[$kCol]]['account_id'];
//                    !isset($re_child['account_name']) &&
//                    $re_child['account_name'] = $reportAccountsGroup[$re_child[$kCol]]['account_name'];
//
//                    $re_child['report_file_id'] = $report_file['id'];
//                    $re[] = array_merge($re_child, $skuGoods);
//                }
//            } else {
//                $list['sku_clean'] = $model_sku->clean($list['sku']);
//                $decodeSkuInfos = $model_sku->decode($list['sku']);
//                $list['sku_serialized'] = serialize($decodeSkuInfos);
//
//                $list['account_id'] = $reportAccountsGroup[$list[$kCol]]['account_id'];
//                $list['account_name'] = $reportAccountsGroup[$list[$kCol]]['account_name'];
//                $list['report_file_id'] = $report_file['id'];
//
//                foreach($decodeSkuInfos as $decodeSkuInfo) {
//                    $skuGoods = array();
//                    $skuGoods['sku_base'] = $decodeSkuInfo['sku'];
//                    $skuGoods['sku_base_quantity'] = $decodeSkuInfo['quantity'];
//
//                    $lists[] = array_merge($list, $skuGoods);
//                }
//            }
        }
        fclose($f);
        return $lists;
        //return empty($cols) ? $lists : $re;
    }

    /**
     * 文件里的内容读取到数据库当中，删除过期的数据
     */
    public function fileContentToDbTable ($tableName, $rowLists,$accountId) {
        if($tableName == 'api_report_sale'){
            $this->reportSaleModel->insertData($tableName,$rowLists);
        }elseif($tableName == 'api_report_unsuppressed_inventory'){
            $this->reportUnsuppressedInventoryModel->insertData($tableName,$rowLists);
            /*把插入的数据再插入api_account_seller_sku表*/
            //$this->accountSellerSkuService->insertToAccountSellerSku();
        } elseif($tableName == 'api_report_inventory'){
            $this->reportInventoryModel->insertData($tableName,$rowLists);
        } elseif ($tableName == 'api_report_receipts') {
            $this->reportReceiptsModel->insertData($tableName,$rowLists);
        } elseif ($tableName == 'api_report_current_inventory') {
            if($this->reportCurrentInventoryModel->insertData($tableName,$rowLists)){
                if(substr($rowLists[0]['snapshot_date'],0,7)==date('Y-m', strtotime(date('Y-m-01', strtotime('-1 month')) . '-1 day'))){
                    $this->reportLog(5,$accountId,'期初库存插入数据库成功',1);
                }else{
                    $this->reportLog(6,$accountId,'期末库存插入数据库成功',1);
                }
            }else{
                if(substr($rowLists[0]['snapshot_date'],0,7)==date('Y-m', strtotime(date('Y-m-01', strtotime('-1 month')) . '-1 day'))){
                    $this->reportLog(5,$accountId,'期初库存插入数据库失败');
                }else{
                    $this->reportLog(6,$accountId,'期末库存插入数据库失败');
                }
            }

        } elseif ($tableName == 'api_report_summary_inventory') {
//            $this->reportSummaryInventoryModel->insertData($tableName,$rowLists);
            if($this->reportSummaryInventoryModel->insertData($tableName,$rowLists)){
                $this->reportLog(7,$accountId,'库存明细插入数据库成功',1);
            }else{
                $this->reportLog(7,$accountId,'库存明细插入数据库失败');
            }
        } else {
            $this->reportRemovalModel->insertData($tableName,$rowLists);
        }

    }

    /**
     * 检查该文件是否为标题解码不出来的文件
     */
    public function checkIsDecodeBlackReport ($report_file, $row) {
        /**其他站点会比jp站点多一个字段，所以跳过查标题黑名单**/
        if ($report_file['report_type_id'] == 5 || $report_file['report_type_id'] == 6 ||$report_file['report_type_id'] == 7) {
            return $row;
        }

        $title_path = $this->reportDir . 'title/title_' . $report_file['report_type_id'] . '.txt';

        $isBlackReport = false;
        foreach (self::$decodeBlackList as $black) {
            if(preg_match('/.*-' . strtoupper($black)  . '/si', $report_file['account_name'])) {
                $isBlackReport = true;
                break;
            }
        }
        if ($isBlackReport) {
            $tf = @fopen($title_path, 'r');
            $re = !feof($tf) ? fgets($tf) : false;
            fclose($tf);

            return $re;
        } elseif(strpos($report_file['account_name'], '-UK') !== false ||
            strpos($report_file['account_name'], '-CA') !== false ||
            strpos($report_file['account_name'], '-US') !== false
        ) {
            file_put_contents($title_path, '');
            file_put_contents($title_path, $row);
        }

        return $row;
    }

    /**
     * 去掉数组元素两边的空格
     */
    public static function trimArray($arr) {
        if (!is_array($arr)) {
            return $arr;
        }
        try {
            while (list($key, $value) = each($arr)) {
                if (is_array($value)) {
                    $arr[$key] = self::trimArray($value);
                } else {
                    $arr[$key] = trim($value);
                }
            }
        } catch (Exception $e){
            echo $e->getMessage();
        }
        return $arr;
    }

    /**
     * 描述：创建文件夹
     * 参数：$dir
     */
    public function mk_dirs($dir){
        if(!is_readable($dir)){
            mkdir(dirname($dir),0777);
            if(!is_file($dir)){
                mkdir($dir,0777);
            }
        }
    }

    /**
     * 描述：通过帐号ID和报告类型查看当天该计划任务是否跑成功
     */
    public function checkCronRun($reportType, $accountId) {
        if (!in_array($reportType['id'], array(4,5,6,7))) {
            return false;
        }
        $map['account_id'] = $accountId;
        if(in_array($reportType['id'], array(4,5))){
            $map['create_time'] = array('like', '%' . date("Y-m-d") .'%');
        }
        if(in_array($reportType['id'], array(6,7))){
            $last['LEFT(snapshot_date,7)'] = date('Y-m', strtotime('-1 month'));
            $last['account_id'] = $accountId;
            $data2 = M($reportType['table_name'], ' ', 'fbawarehouse')
                ->where($last)
                ->find();
            if (empty($data2) && count($data2)==0) {
                return false;
            }else{
                $map['LEFT(snapshot_date,7)'] = date('Y-m', strtotime('-2 month'));
            }
        }
        $data = M($reportType['table_name'], ' ', 'fbawarehouse')
            ->where($map)
            ->find();
        if (!empty($data)) {
            return true;
        } else {
            if(in_array($reportType['id'], array(6,7))){
                $fileData = array();
            }
            if(in_array($reportType['id'], array(4,5))){
                $map['report_type_id'] = $reportType['id'];
                $fileData = M('api_report_files', ' ', 'fbawarehouse')
                    ->where($map)
                    ->find();
            }
            if (!empty($fileData)) {
                return true;
            } else {
                return false;
            }
        }

    }

    /**
     * 描述：解析计划任务中没有解析的文件
     */
    public function analyzeUnAnalyzeFile($reportId = NULL) {
        $files = $this->reportFileModel->getUnAnalyzeFile($reportId);
        $reportType = $this->reportTypeModel->getReportType();

        if (!empty($files)) {
            foreach ($files as $file) {
                $reportFilePath = $this->reportDir . $file['report_type_id'] . '/' . $file['account_name']. '/' .$file['file_name'];
                $rowLists = $this->goAnalysisReport($file, $reportFilePath);
                $this->fileContentToDbTable ($reportType[$file['report_type_id']]['table_name'], $rowLists,$file['account_id']);
            }
        }

    }

    public function reportLog($type, $accountId, $remark, $ok = null) {
        $logModel = M('api_report_log', ' ', 'fbawarehouse');
        $data =  array(
            'account_id' => $accountId,
            'date' => date('d')==31?date('Y-m', strtotime('-1 month -1 day')):date('Y-m', strtotime('-1 month')),
            'report_type' => $type,
            'is_ok' => $ok==1?$ok:0,
            'remark' => $remark,
            'create_time' => date('Y-m-d H:i:s')
        );
        $logModel->add($data);
    }
}